home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / NR4TIMER.C < prev    next >
Text File  |  1993-08-09  |  4KB  |  154 lines

  1. /* net/rom level 4 (transport) protocol timer management.
  2.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  3.  * non-commercial distribution only.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "config.h"
  9. #ifdef NETROM
  10. #include "mbuf.h"
  11. #include "timer.h"
  12. #include "ax25.h"
  13. #include "netrom.h"
  14. #include "nr4.h"
  15. #include <ctype.h>
  16.  
  17. #undef NR4DEBUG
  18.  
  19. /* The ACK timer has expired without any data becoming available.
  20.  * Go ahead and send an ACK.
  21.  */
  22. void
  23. nr4ackit(p)
  24. void *p ;
  25. {
  26.     struct nr4cb *cb  = (struct nr4cb *)p ;
  27.     struct nr4hdr rhdr ;
  28.  
  29. #ifdef NR4DEBUG
  30.     tputs("ACKIT called.\n") ;
  31. #endif
  32.  
  33.     rhdr.opcode = (cb->qfull) ? (NR4OPACK | NR4CHOKE) : NR4OPACK;
  34.     rhdr.yourindex = cb->yournum ;
  35.     rhdr.yourid = cb->yourid ;
  36.     rhdr.u.ack.rxseq = cb->rxpected ;
  37.     nr4sframe(cb->remote.node, &rhdr, NULLBUF) ;
  38. }
  39.  
  40. /* Called when one of the transmit timers has expired */
  41. void
  42. nr4txtimeout(p)
  43. void *p ;
  44. {
  45.     struct nr4cb *cb = (struct nr4cb *)p ;
  46.     unsigned seq ;
  47.     struct nr4txbuf *t ;
  48.  
  49.     /* Sanity check */
  50.     if (cb->state != NR4STCON)
  51.         return ;
  52.  
  53.     /* Scan through the send window looking for expired timers */
  54.     for (seq = cb->ackxpected ;
  55.       nr4between(cb->ackxpected, seq, cb->nextosend) ;
  56.       seq = (seq + 1) & NR4SEQMASK) {
  57.         t = &cb->txbufs[seq % cb->window] ;
  58.  
  59.         if (t->tretry.state == TIMER_EXPIRE) {
  60.             t->tretry.state = TIMER_STOP ;    /* So we don't do it again */
  61.  
  62.             if (t->retries == Nr4retries) {
  63.                 cb->dreason = NR4RTIMEOUT ;
  64.                 nr4state(cb, NR4STDISC) ;
  65.             }
  66.             t->retries++ ;
  67.  
  68.             /* We keep track of the highest retry count in the window. */
  69.             /* If packet times out and its new retry count exceeds the *
  70.             /* max, we update the max and bump the backoff level.  This */
  71.             /* expedient is to avoid bumping the backoff level for every */
  72.             /* expiration, since with more than one timer we would back */
  73.             /* off way too fast (and at a rate dependent on the window */
  74.             /* size! */
  75.  
  76.             if (t->retries > cb->txmax) {
  77.                 cb->blevel++ ;
  78.                 cb->txmax = t->retries ;    /* update the max */
  79.             }
  80.             nr4sbuf(cb,seq) ;    /* Resend buffer */
  81.         }
  82.      }
  83. }
  84.  
  85. /* Connect/disconnect acknowledgement timeout */
  86. void
  87. nr4cdtimeout(p)
  88. void *p ;
  89. {
  90.     struct nr4cb *cb = (struct nr4cb *)p ;
  91.     struct nr4hdr hdr ;
  92.  
  93.     switch(cb->state) {
  94.       case NR4STCPEND:
  95.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  96.             cb->dreason = NR4RTIMEOUT ;
  97.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  98.         } else {
  99.             /* Set up header */
  100.             hdr.opcode = NR4OPCONRQ ;
  101.             hdr.u.conreq.myindex = cb->mynum ;
  102.             hdr.u.conreq.myid = cb->myid ;
  103.             hdr.u.conreq.window = Nr4window ;
  104.             memcpy(hdr.u.conreq.user,cb->local.user,AXALEN) ;
  105.             memcpy(hdr.u.conreq.node,cb->local.node,AXALEN) ;
  106.  
  107.             /* Bump tries counter and backoff level, and restart timer */
  108.             /*áWe use a binary exponential backoff. */
  109.             cb->cdtries++ ;
  110.             cb->blevel++ ;
  111.             set_timer(&cb->tcd,(int32)min(dur_timer(&cb->tcd)+cb->srtt,300000L));
  112.             start_timer(&cb->tcd) ;
  113.  
  114.             /* Send connect request packet */
  115.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  116.         }
  117.         break ;
  118.  
  119.       case NR4STDPEND:
  120.           if (cb->cdtries == Nr4retries) {    /* Have we tried long enough? */
  121.             cb->dreason = NR4RTIMEOUT ;
  122.             nr4state(cb, NR4STDISC) ;        /* Give it up */
  123.         } else {
  124.             /* Format header */
  125.             hdr.opcode = NR4OPDISRQ ;
  126.             hdr.yourindex = cb->yournum ;
  127.             hdr.yourid = cb->yourid ;
  128.  
  129.             /* Bump retry count and start timer */
  130.             /* We don't really need to be fancy here, since we */
  131.             /* should have a good idea of the round trip time by now. */
  132.             cb->cdtries++ ;
  133.             start_timer(&cb->tcd) ;
  134.  
  135.             /* Send disconnect request packet */
  136.             nr4sframe(cb->remote.node,&hdr, NULLBUF) ;
  137.         }
  138.         break ;
  139.     }
  140. }
  141.  
  142. /* The choke timer has expired.  Unchoke and kick. */
  143.  
  144. void
  145. nr4unchoke(p)
  146. void *p ;
  147. {
  148.     struct nr4cb *cb = (struct nr4cb *)p ;
  149.  
  150.     cb->choked = 0 ;
  151.     nr4output(cb) ;
  152. }
  153.  
  154. #endif /* NETROM */